// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using System.Linq;
using System.Reflection;
using Microsoft.Practices.Unity.InterceptionExtension;
using ValidationAspects.Sdk.Interception;

namespace ValidationAspects.Unity
{
	public class ValidationCallHandler : ICallHandler
	{
		#region Implementation of ICallHandler
		public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
		{
			MethodBase methodBase = input.MethodBase;
			if (methodBase.DeclaringType != input.Target.GetType())
				methodBase = input.Target.GetType().GetMethod(input.MethodBase.Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

			object[] parameters = input.Arguments.Cast<object>().ToArray();

			// is this a property?		
			if (methodBase.IsSpecialName)
			{
				if (methodBase.Name.StartsWith("set_"))
				{
					try
					{
						InterceptValidate.Property(methodBase.DeclaringType.GetProperty(methodBase.Name.Remove(0, 4)), input.Target, parameters[0]);
					}
					catch (ValidationException e)
					{
						return input.CreateExceptionMethodReturn(e);
					}
				}
			}
			else
			{
				try
				{
					InterceptValidate.Method(methodBase, input.Target, parameters);
				}
				catch (ValidationException e)
				{
					return input.CreateExceptionMethodReturn(e);
				}
			}

			return getNext()(input, getNext);
		}

		public int Order { get; set; }
		#endregion
	}
}